package mywebapps.security;

import java.io.IOException;

import javax.faces.application.FacesMessage;
import javax.faces.event.ActionEvent;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import mywebapps.common.Constants;
import mywebapps.common.jsf.BaseAction;

import org.springframework.security.Authentication;
import org.springframework.security.AuthenticationManager;
import org.springframework.security.BadCredentialsException;
import org.springframework.security.context.HttpSessionContextIntegrationFilter;
import org.springframework.security.context.SecurityContext;
import org.springframework.security.context.SecurityContextHolder;
import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
import org.springframework.security.ui.AbstractProcessingFilter;
import org.springframework.security.ui.WebAuthenticationDetails;
import org.springframework.security.ui.savedrequest.SavedRequest;
import org.springframework.security.ui.webapp.AuthenticationProcessingFilter;

public class LoginBean extends BaseAction
{
    private String username;
    private String password;
    private AuthenticationManager authenticationManager;
    
    
    public void login(ActionEvent event)
    {
        try {
            final HttpServletRequest request = getRequest();
            final HttpSession session = request.getSession();
            session.setAttribute(AuthenticationProcessingFilter.SPRING_SECURITY_LAST_USERNAME_KEY, username );

            //perform authentication
            final Authentication auth = getAuthenticationManager().authenticate(createAuthentication());
         
            //initialize the security context.
            final SecurityContext secCtx = SecurityContextHolder.getContext();
            secCtx.setAuthentication( auth );
            session.setAttribute( HttpSessionContextIntegrationFilter.SPRING_SECURITY_CONTEXT_KEY, secCtx );
         
            redirectToPreviousURL(session);
        } catch (BadCredentialsException bce) {
            try {
                getFacesContext().getExternalContext().redirect(Constants.CONTEXT_PATH + "/pages/login.jsf?login_error=1");
            } catch(IOException ioe) {
                getFacesContext().addMessage( null, new FacesMessage( ioe.getMessage() ) );
            }
        } catch ( Exception e ) {
            getFacesContext().addMessage( null, new FacesMessage( e.getMessage() ) );
            e.printStackTrace();
            try {
                getFacesContext().getExternalContext().redirect(Constants.CONTEXT_PATH + "/pages/login.jsf");
            } catch(IOException ioe) {
                getFacesContext().addMessage( null, new FacesMessage( ioe.getMessage() ) );
            }
        }
    }
    
    private Authentication createAuthentication() 
    {
        final UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(username, password );
        final HttpServletRequest request = getRequest();
        authToken.setDetails(new WebAuthenticationDetails(request));
        return authToken;
    }
    
    private void redirectToPreviousURL(HttpSession session) throws IOException
    {
        SavedRequest savedRequest = (SavedRequest) session.getAttribute(AbstractProcessingFilter.SPRING_SECURITY_SAVED_REQUEST_KEY);
        
        String url = null;
        if (savedRequest != null) {
            if (savedRequest.getFullRequestUrl().indexOf("logout") == -1) {
                url = savedRequest.getFullRequestUrl();
            }
        }
        
        if (url == null) {
            url = Constants.CONTEXT_PATH + "/pages/user/dashboard.jsf";
        }
        
        getFacesContext().getExternalContext().redirect(url);
    }
    
    protected HttpServletRequest getRequest() 
    {
        return (HttpServletRequest) getFacesContext().getExternalContext().getRequest();            
    }
    
    public AuthenticationManager getAuthenticationManager()
    {
        return authenticationManager;
    }
    
    public void setAuthenticationManager(AuthenticationManager authenticationManager)
    {
        this.authenticationManager = authenticationManager;
    }
    
    public String getUsername()
    {
        return username;
    }
    
    public void setUsername(String username)
    {
        this.username = username;
    }
    
    public String getPassword()
    {
        return password;
    }
    
    public void setPassword(String password)
    {
        this.password = password;
    }
    
//    public void login(ActionEvent e) throws IOException 
//    {
//        FacesContext context = FacesContext.getCurrentInstance();
//        
//        context.getExternalContext().dispatch(
//                "/pages/loginProcess?j_username=" 
//                + username + "&j_password=" + password);
//    }
}
